package com.teacher.hong.aspect;

import com.teacher.hong.entity.Clazz;
import com.teacher.hong.entity.SystemLog;
import com.teacher.hong.service.ISystemLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 定义 Service接口的切面
 */
@Slf4j
@Aspect
@Component
public class ServiceAspect {

    /**
     * 定义切入点
     */
    @Pointcut("execution(* com.teacher.hong.service.impl.*ServiceImpl.*(..))")
    private void method() {}


    /**
     * 定义前置通知
     * @param joinPoint 加入点
     */
    @Before("method()")
    public void actionBefore(JoinPoint joinPoint) {
        log.debug("增加的前置代码...执行方法：" + joinPoint.getSignature().getName() + "\t参数数量：" + joinPoint.getArgs().length + "\t" + LocalDateTime.now());
        recordSystemLog(joinPoint.getSignature().toShortString(), "前置通知", joinPoint.getArgs().length, "");
    }


    /**
     * 定义返回结果通知
     * @param joinPoint 加入点
     * @param object    返回结果
     */
    @AfterReturning(pointcut = "method()", returning = "object")
    public void actionReturning(JoinPoint joinPoint, Object object) {
        log.debug("增加的获取返回结果代码...执行方法：" + joinPoint.getSignature().getName() + "\t返回：" + (object != null ? object : "无") + "\t" + LocalDateTime.now());
        recordSystemLog(joinPoint.getSignature().toShortString(), "返回结果通知", joinPoint.getArgs().length, object != null ? object : "");
    }

    /**
     * 定义后置通知
     * @param joinPoint 加入点
     */
    @After("method()")
    public void actionAfter(JoinPoint joinPoint) {
        log.debug("增加的后置代码...执行方法：" + joinPoint.getSignature().getName() + "\t" + LocalDateTime.now());
        recordSystemLog(joinPoint.getSignature().toShortString(), "后置通知", joinPoint.getArgs().length, "");
    }

    /**
     * 定义异常通知
     * @param joinPoint 加入点
     * @param e         触发的异常
     */
    @AfterThrowing(pointcut = "method()", throwing = "e")
    public void actionThrowing(JoinPoint joinPoint, Exception e) {
        log.debug("增加的处理异常的代码...异常：" + e.getMessage() + "\t" + LocalDateTime.now());
        recordSystemLog(joinPoint.getSignature().toShortString(), "异常通知", joinPoint.getArgs().length, e.getMessage());
    }


    /**
     * 定义环绕通知
     * @param joinPoint 加入点
     */
    @Around("method()")
    public Object actionAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.debug("增加的环绕代码...执行方法：" + joinPoint.getSignature().getName() + "\t" + joinPoint.getSignature().toShortString() + "\t" + joinPoint.getTarget() + "\t" + LocalDateTime.now());

        //执行原来的方法，并获取其返回结果赋值于result
        Object result = joinPoint.proceed();
        switch (joinPoint.getSignature().toShortString()) {
            case "ClazzServiceImpl.list()":
                //对原来获取的结果进行手动干预（改值）
                List<Clazz> clazzList = (List<Clazz>) result;
                clazzList.add(new Clazz(20, "六年级1班"));
                clazzList.remove(0);
                return clazzList;
        }


        recordSystemLog(joinPoint.getSignature().toShortString(), "环绕通知", joinPoint.getArgs().length, result);
        return result;
    }


    @Resource
    ISystemLogService systemLogService;

    /**
     * 记录操作日志
     * @param method
     * @param notice
     * @param paramCount
     * @param returnValue
     */
    private void recordSystemLog(String method, String notice, int paramCount, Object returnValue) {
        SystemLog systemLog = new SystemLog(method, notice, paramCount, returnValue == null ? null : returnValue.toString());
        //保存日志
        systemLogService.save(systemLog);
    }


}
